// Copyright 2023 Huawei Cloud Computing Technology Co., Ltd.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#ifndef PACKET_MANAGER_H
#define PACKET_MANAGER_H

#include <cstdint>
#include <mutex>
#include <array>
#include "Include/msghead.h"
#include "PacketQueue.h"

class PacketManager {
public:
    /*
     * @功能描述：获得PacketManager单例
     * @返回值：PacketManager单例
     */
    static PacketManager* GetInstance();
    /*
     * @功能描述：销毁PacketManager单例
     */
    static void CloseInstance();
    /*
     * @功能描述：创建指定类型的数据包队列，不加锁，不支持在多线程情况下创建和删除队列
     * @参数 [in] type：数据包类型
     * @参数 [in] isBlock：是否阻塞
     * @返回值：成功返回true，失败返回false
     */
    bool CreateQueue(VMIMsgType type, bool isBlock);
    /*
     * @功能描述：把数据包加入指定类型的队列
     * @参数 [in] type：数据包类型
     * @参数 [in] packet：数据包的地址和大小
     * @返回值：成功返回true，失败返回false
     */
    bool PutPkt(VMIMsgType type, const std::pair<uint8_t *, uint32_t> &packet);
    /*
     * @功能描述：从指定数据包队列中取出包
     * @参数 [in] data：数据地址
     * @参数 [in] length：数据大小
     * @返回值：验证参数非法返回空pair，有数据包返回其地址和大小，没有数据包，阻塞模式下等待，非阻塞模式返回空pair
     */
    std::pair<uint8_t *, uint32_t> GetNextPkt(VMIMsgType type);
    /*
     * @功能描述：清空所有数据包队列
     */
    void ClearPkt();
    /*
     * @功能描述：清空指定类型的数据包队列
     * @参数 [in] type：数据包队列的类型
     */
    void ClearQueue(VMIMsgType type);
    /*
     * @功能描述：撤销指定类型的数据包队列
     * @参数 [in] type：数据包队列的类型
     */
    void Cancel(VMIMsgType type);
    /*
     * @功能描述：恢复指定类型的数据包队列
     * @参数 [in] type：数据包队列类型
     */
    void Continue(VMIMsgType type);

private:
    /*
     * @功能描述：构造函数，初始化包队列数组为空
     */
    PacketManager();
    /*
     * @功能描述：析构函数，销毁数据包队列
     */
    ~PacketManager();
    /*
     * @功能描述：验证数据包队列类型和对应的数据包队列是否存在
     * @参数 [in] type：数据包队列类型
     * @返回值：类型合法且数据包队列存在返回true，否则返回false
     */
    bool Verify(VMIMsgType type);

    std::array<std::shared_ptr<PacketQueue>, VMIMsgType::End> m_packetQueues = {};
    static std::mutex g_mutex;
    static PacketManager* g_instance;
};
#endif
